﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace DataAccess
{
    public class DB2DataAccess: AbstractDataAccess
    {
        private DB2Connection m_db2Connection;
		private IBM.Data.DB2.DB2Transaction trans=null;

		#region 构造函数
		/// <summary>
		/// 默认构造函数
		/// </summary>
		public DB2DataAccess()
		{
			//
			// TODO: 在此处添加构造函数逻辑
			//
		}
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="con">DB2数据连接对象</param>
		public DB2DataAccess(DB2Connection con)
		{
			this.m_db2Connection=con;
		}
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="conString">数据库连接字符串</param>
		public DB2DataAccess(string conString)
		{
			this.m_db2Connection=new DB2Connection(conString);
		}
		#endregion

		#region 属性
		/// <summary>
		/// 返回数据库类型枚举成员(DatabaseType)
		/// </summary>
		public override DatabaseType DatabaseType
		{
			get
			{
				return DatabaseType.DB2;
			}
		}
		/// <summary>
		/// 返回数据库连接接口
		/// </summary>
		public override System.Data.IDbConnection DbConnection
		{
			get
			{
				return m_db2Connection;
			}
		}
		#endregion
		
		#region IDataAccess成员
		/// <summary>
		/// 开始一个事务
		/// </summary>
		/// <returns>数据库事务接口</returns>
		public override System.Data.IDbTransaction BeginTransaction()
		{
			trans=this.m_db2Connection.BeginTransaction();
			return trans;
		}
		/// <summary>
		/// 执行SQL语句,返回DataSet对象.
		/// </summary>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">SQL语句的参数集合</param>
		/// <param name="ds">DataSet对象</param>
		/// <param name="tableName">DataSet中表的名称</param>
		/// <returns>DataSet对象</returns>
		public override System.Data.DataSet ExecuteDataset(System.Data.CommandType commandType, string commandText, QueryParameterCollection commandParameters, System.Data.DataSet ds, string tableName)
		{
			DB2Command cmd=new DB2Command();
			PrepareCommand(cmd,commandType, commandText,commandParameters);

			DB2DataAdapter da=new DB2DataAdapter(cmd);
			if(Object.Equals(tableName,null) || (tableName.Length<1))
				da.Fill(ds);
			else
				da.Fill(ds,tableName);
			for(int j=0;j<cmd.Parameters.Count;j++)
			{
				if (cmd.Parameters[j].Direction==ParameterDirection.Output)
					commandParameters[j].Value=cmd.Parameters[j].Value;
			}
			cmd.Parameters.Clear();
			return ds;
		}

		public override DataSet ExecuteDataset(string commandText, QueryParameterCollection commandParameters,DataSet ds,int startRecord,int maxRecords,string tableName)
		{
			DB2Command cmd=new DB2Command();
			PrepareCommand(cmd,CommandType.Text, commandText,commandParameters);

			DB2DataAdapter da=new DB2DataAdapter(cmd);
			if(Object.Equals(tableName,null) || (tableName.Trim() == string.Empty))
				da.Fill(ds);
			else
				da.Fill(ds,startRecord,maxRecords,tableName);
			cmd.Parameters.Clear();
			return ds;
		}

		/// <summary>
		/// 执行SQL语句
		/// </summary>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">SQL语句的参数集合</param>
		/// <param name="row">DataRow对象</param>
		/// <param name="sqlStruct">SqlStruct对象,封装Sql语句及参数</param>
		/// <returns>执行SQL语句影响的行数</returns>
		public override int ExecuteNonQuery(System.Data.CommandType commandType, string commandText, QueryParameterCollection commandParameters, System.Data.DataRow row, SqlStruct sqlStruct)
		{
			DB2Command cmd=new DB2Command();
			if(sqlStruct == null)
				PrepareCommand(cmd,commandType, commandText,commandParameters);
			else
			{
				for(int i=0;i<sqlStruct.ParamFields.Length;i++)
				{
                    if(sqlStruct.ParamFields[i].ParamName.IndexOf('_')!=1)
					    commandParameters.Add(sqlStruct.ParamFields[i].ParamName,row[sqlStruct.ParamFields[i].FieldName]);	
                    else
                        commandParameters.Add(sqlStruct.ParamFields[i].ParamName, row[sqlStruct.ParamFields[i].FieldName, DataRowVersion.Original]);
                }
				PrepareCommand(cmd,CommandType.Text,sqlStruct.SqlString,commandParameters);
			}
			int tmpValue=cmd.ExecuteNonQuery();
			for(int j=0;j<cmd.Parameters.Count;j++)
			{
				if (cmd.Parameters[j].Direction==ParameterDirection.Output)
					commandParameters[j].Value=cmd.Parameters[j].Value;
			}
			cmd.Parameters.Clear();
			return tmpValue;
		}
		/// <summary>
		/// 执行SQL语句,返回IDataReader接口
		/// </summary>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">QueryParameter集合,SQL语句的参数集合</param>
		/// <returns>IDataReader</returns>
		public override System.Data.IDataReader ExecuteReader(System.Data.CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			DB2Command cmd=new DB2Command();
			PrepareCommand(cmd,commandType, commandText,commandParameters);
			IBM.Data.DB2.DB2DataReader dr=cmd.ExecuteReader();
			cmd.Parameters.Clear();
			return dr;
		}
		/// <summary>
		/// 执行SQL语句,返回object接口
		/// </summary>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">QueryParameter集合,SQL语句的参数集合</param>
		/// <returns>object</returns>
		public override object ExecuteScalar(System.Data.CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			DB2Command cmd=new DB2Command();
			PrepareCommand(cmd,commandType, commandText,commandParameters);
			object tmpValue=cmd.ExecuteScalar();
			cmd.Parameters.Clear();
			return tmpValue;
		}
		/// <summary>
		/// 执行SQL语句,返回XmlReader对象
		/// </summary>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">QueryParameter集合,SQL语句的参数集合</param>
		/// <returns>XmlReader</returns>
		public override System.Xml.XmlReader ExecuteXmlReader(System.Data.CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			DB2Command cmd=new DB2Command();
			PrepareCommand(cmd,commandType, commandText,commandParameters);
			XmlReader reader=cmd.ExecuteXmlReader();
			cmd.Parameters.Clear();
			return reader;
		}

		#endregion 
		/// <summary>
		/// 处理DB2Command对象,设置参数等信息.
		/// </summary>
		/// <param name="cmd">DB2Command对象</param>
		/// <param name="commandType">CommandType对象</param>
		/// <param name="commandText">要执行的SQL语句</param>
		/// <param name="commandParameters">QueryParameter集合,SQL语句的参数集合</param>
		private void PrepareCommand(DB2Command cmd,CommandType commandType, string commandText, QueryParameterCollection commandParameters)
		{
			commandText = commandText.Replace(":","@");
			cmd.CommandType=commandType;
			cmd.CommandText=commandText;
			cmd.Connection=this.m_db2Connection;
			cmd.Transaction = trans;
			cmd.CommandTimeout=60;
			if((commandParameters!=null) && (commandParameters.Count>0) )
			{
				for(int i=0;i<commandParameters.Count;i++)
				{
					cmd.Parameters.Add(commandParameters[i].ParameterName,commandParameters[i].Value);
					cmd.Parameters[i].Direction=commandParameters[i].Direction;
					if(commandParameters[i].Db2Type!=DB2Type.Invalid)
						cmd.Parameters[i].DB2Type=commandParameters[i].Db2Type;
				}
			}
		}
	}
    
}
